home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/gawk -f
- # @(#) filegroup.gawk 3.2 95/01/14
- # 94/03/04 john h. dubois iii (john@armory.com)
- # 94/08/04 Added q & a options. Bugfixes.
- # 94/08/07 Converted to #!awk program.
- # 94/08/10 Added x option.
- # 94/09/22 Warn about groups with status 'n'. Added pgt options.
- # Use status translation table.
- # 94/11/09 Added -XYNS
- # 94/11/16 Added multiple debug levels. Fixed Report logic.
- # 94/11/21 Added rR opts, and "r" status.
- # 94/12/12 Made a option work again
- # 95/01/14 Only accept legal statuses wtih -a.
-
- # filegroup: change status of group reception
- # Meaning of status:
- # y: spool group
- # n: spool group but do not allow posting
- # x: do not spool group
- # m: spool group & send postings to moderator
- # =: postings to group should be spooled in a different group.
- # This is extended with 'xm' to mean that group should not be spooled,
- # while retaining the information that if it is changed to spooled status it
- # should be moderated.
-
- BEGIN {
- Setup(Groups,VerboseState)
-
- while ((GlobAct || NumGroups || Change) && (ret = (getline < active)) == 1)
- if (GlobAct || $1 in Groups) {
- if (Report)
- printf "%s %s\n",$1,VerboseState[$4]
- else if (ModifyGroup($1,$2,$3,$4,NewStatus,NewActive)) {
- Change = 1
- if (Debug > 1)
- printf "Modified specified group %s\n",$1 > "/dev/stderr"
- }
- NumGroups--
- delete Groups[$1]
- }
- else if (UseNSTable) {
- if (ModifyGroup($1,$2,$3,$4,NSTable,NewActive)) {
- Change = 1
- if (Debug > 1)
- printf "Modified non-specified group %s\n",$1 \
- > "/dev/stderr"
- }
- }
- else if (!Report) # If not just reporting
- print $0 > NewActive
-
- if (ret == -1) {
- printf "Error reading active file '%s'. Exiting.\n",
- active > "/dev/stderr"
- exit 1
- }
-
- if (NumGroups > 0) {
- if (Debug)
- printf "%d groups not found in active file.\n",NumElem(Groups) \
- > "/dev/stderr"
- if (CreationStatus != "") {
- for (Group in Groups)
- printf "%s 0000000000 00001 %s\n",Group,CreationStatus \
- > NewActive
- print \
- "These groups do not exist in the active file (adding them):" \
- > "/dev/stderr"
- Change = 1
- }
- else {
- print "These groups do not exist in the active file:" \
- > "/dev/stderr"
- }
- for (Group in Groups)
- print Group > "/dev/stderr"
- }
- if (Debug)
- printf "Change=%d\n",Change > "/dev/stderr"
- if (Change && !Report && !Test)
- system("a=" active "; chmod 664 $a+ && chgrp news $a+ &&"\
- " chown news $a+ && ln $a $a- && mv $a+ $a")
- exit 0
- }
-
- # Sets globals:
- # active Active file name
- # NewActive Name of new active file.
- # Quiet Do not warn about groups that were already on.
- # CreationStatus Status of groups to be added to active file.
- # Debug Debugging level.
- # Report Whether group status should be reported only.
- # NumGroups Number of groups to process.
- # GlobAct Act on all newsgroups.
- # Test Do not move new active file into place.
- # UseNSTable Use the NSTable for groups not specified.
- # NewStatus[] Translation table from old status -> new status
- # NSTable[] Translation table for groups not specified.
- # Groups[] Names of groups to process.
- # VerboseState[] Name for each possible state.
- function Setup(Groups,VerboseState, Name,Usage) {
- Name = "filegroup"
- Usage = \
- "Usage: " Name " [-hnxydqgt] [-d<debug-level>] [-a<status>] [-A<active-file>]\n"\
- " [-s<translation-table> [newsgroup ...]"
- active = "/usr/lib/news/active"
- Report = 1
- # Opts normally uses -x to turn on debugging; removed that code.
- ARGC = Opts(Name,Usage,"a:d>A:ghnrqs:txyXYNRS:",0)
-
- if ("h" in Options) {
- printf \
- "%s: display or change status of newsgroup reception.\n"\
- "%s\n"\
- "If no flags are given, %s displays the reception status of the named\n"\
- "newsgroups.\n"\
- "If no newsgroups are named, the standard input is read for group names.\n"\
- "Options:\n"\
- "-a<status>: Add any groups that do not exist in the active file, with the\n"\
- " given status (y, n, or x). Note that this will be incorrect for any\n"\
- " groups that should be moderated.\n"\
- "-g: Act on all groups. No group names should be given with this option.\n"\
- "-A<active-file>: Use <active-file> instead of %s.\n"\
- "-t: Test. Leave updated active file in active-file-name+; do not move it\n"\
- " in place of the original file.\n"\
- "-h: Print this help.\n"\
- "-x: Turn off reception of the named newsgroups. y and n are changed to x,\n"\
- " m is changed to xm.\n"\
- "-y: Turn on reception of the named newsgroups. x and n are changed to y,\n"\
- " xm is changed to m.\n"\
- "-n: Mark the newsgroups as local posting disallowed. y is changed to n.\n"\
- "-r: Remove the named newsgroups from the active file.\n"\
- "-s<translation-table>: Give a specific status translation table, in the\n"\
- " form old=new[:old=new...], where each old=new pair gives a new status\n"\
- " that each group with the old status should be set to. A new status of\n"\
- " 'r' means that groups with the given old status will be removed from\n"\
- " the active file.\n"\
- "-[XYNRS]: Like -[xynrs], but act on groups *not* named. One of these can\n"\
- " be used to set the \"default\" reception status at the same time that\n"\
- " one of -[xynrs] is used to set a specific status for the named groups.\n"\
- "-d<debug-level>: Turn on debugging. 1 prints minimal debugging info;\n"\
- " 2 prints per-group debugging info.\n"\
- "-q: Do not warn about groups whose status is not changed.\n",
- Name,Usage,Name,active
- exit 0
- }
- Quiet = "q" in Options
- if ((CreationStatus = Options["a"]) != "") {
- if (CreationStatus !~ /^([ynmx]|xm)$/) {
- printf "Bad status '%s' given with -a. Exiting.\n",
- CreationStatus > "/dev/stderr"
- exit 1
- }
- else
- Report = 0
- }
- if ("d" in Options)
- Debug = Options["d"]
- Test = "t" in Options
-
- if ((GlobAct = ("g" in Options)) && ARGC > 1) {
- print "No group names should be given with -g. Exiting.\n" \
- > "/dev/stderr"
- exit 1
- }
-
- if ("A" in Options)
- active = Options["A"]
- NewActive = active "+"
-
- if (!GlobAct) {
- if (ARGC > 1) {
- for (i = 1; i < ARGC; i++)
- Groups[ARGV[i]]
- }
- else
- while (getline < "/dev/stdin" == 1)
- MakeSet(Groups,$0,FS)
- delete Groups[""]
-
- # Do not rely on the return value of MakeSet,
- # since groups might be named more than once.
- NumGroups = NumElem(Groups)
- if (!NumGroups) {
- printf "%s: No groups specified.\n",Name > "/dev/stderr"
- exit 1
- }
- }
-
- InitArr(VerboseState,"x:m:xm:y:n:r","not spooled:moderated:"\
- "not spooled (moderated):spooled:spooled (local posting disabled):"\
- "removed from active",":")
-
- Report = \
- MakeTable(NewStatus,"x","y","n","r","s",Options,VerboseState) && Report
- UseNSTable = !MakeTable(NSTable,"X","Y","N","R","S",Options,VerboseState)
- Report = !UseNSTable && Report
- if (Debug)
- printf "Report=%d Test=%d GlobAct=%d\n",Report,Test,GlobAct \
- > "/dev/stderr"
- }
-
- # Returns 0 if any of x y n r s is in Options, else returns 1.
- function MakeTable(Table,x,y,n,r,s,Options,States,
- Report,Pair,Pairs,Elem,i,Type) {
- Report = 1
-
- if (x == "X")
- Type = "non-"
-
- if (y in Options) {
- Table["x"] = "y"
- Table["n"] = "y"
- Table["xm"] = "m"
- Report--
- }
- if (x in Options) {
- Table["y"] = "x"
- Table["n"] = "x"
- Table["m"] = "xm"
- Report--
- }
- if (n in Options) {
- Table["y"] = "n"
- Report--
- }
- if (r in Options) {
- Table["y"] = "r"
- Table["n"] = "r"
- Table["m"] = "r"
- Table["x"] = "r"
- Table["xm"] = "r"
- Report--
- }
- if (s in Options) {
- split(Options[s],Pairs,":")
- for (Pair in Pairs) {
- if (split(Pairs[Pair],Elem,"=") != 2) {
- printf "Bad format in -%s translation table.\n",
- s > "/dev/stderr"
- exit 1
- }
- if (!(Elem[1] in States) || !(Elem[2] in States)) {
- printf \
- "Unknown state in -%s translation table; must be one of [x m xm y n r]\n",s \
- > "/dev/stderr"
- exit 1
- }
- Table[Elem[1]] = Elem[2]
- }
- Report--
- }
- if (Debug) {
- printf "Status translation table for %sspecified groups:\n",
- Type > "/dev/stderr"
- for (i in Table)
- printf "%s -> %s\n",i,Table[i] > "/dev/stderr"
- }
- if (Report < 0) {
- printf "Error in new status for %sspecified groups:"\
- " must give only one of -[%s%s%s%s].\n",Type,x,y,n,s > "/dev/stderr"
- exit 1
- }
- return Report
- }
-
- # Return value: 0 if no change, 1 if status changed.
- # Writes a line for group Group to file NewActive.
- # The first three fields of the line written are Group, c1, and c2.
- # The 4th field is the translation for Status.
- function ModifyGroup(Group,c1,c2,Status,XTable,NewActive,
- NewState) {
- if (!(Status in XTable)) {
- if (Quiet != 1)
- printf "%s not modified; had status: %s\n",Group,
- Status in VerboseState ? VerboseState[Status] : Status \
- > "/dev/stderr"
- print Group " " c1 " " c2 " " Status > NewActive
- return 0
- }
- else {
- NewState = XTable[Status]
- printf "%s: %s -> %s\n",Group,VerboseState[Status],
- VerboseState[NewState] > "/dev/stderr"
- if (NewState != "r")
- printf "%s %s %s %s\n",Group,c1,c2,NewState > NewActive
- return 1
- }
- }
-
- # InitArr: Initialize an array with values.
- # Ind and Vals are separated into lists on Sep.
- # For each item in Ind, an index with that name is created in Arr[],
- # and the value with the same position in Vals is stored in it.
- # Global variables: none.
- function InitArr(Arr,Ind,Vals,sep, numind,indnames,values) {
- split(Ind,indnames,sep)
- split(Vals,values,sep)
- for (numind in indnames)
- Arr[indnames[numind]] = values[numind]
- }
-
- function ClearArr(Arr, Elem) {
- for (Elem in Arr)
- delete Arr[Elem]
- }
- # Subtract the values in Subtrahend from those in Minuend
- function SubtractArr(Minuend,Subtrahend, Elem) {
- for (Elem in Subtrahend)
- Minuend[Elem] -= Subtrahend[Elem]
- }
-
- # For each element of the array In, an element is created in Out having
- # an index equal to the value of the element in In and a value equal to
- # the index of the element in In.
- function Invert(In,Out,Index) {
- for (Index in In)
- Out[In[Index]] = Index
- }
-
- # Assign: make an array from a list of assignments.
- # An index with the name of each variable in the list is created in the array.
- # Its value is set to the value given for the
- # Input variables:
- # Elements is a string containing the list of variable-value pairs.
- # Sep is the string that separates the pairs in the list.
- # AssignOp is the string that separates variables from values.
- # Output variables:
- # Arr is the array.
- # Return value: the number of elements added to the set.
- # Example:
- # Assign(Arr,"foo=blot bar=blat baz=blit"," ","=")
- function Assign(Arr,Elements,Sep,AssignOp,
- Num,Names,Elem,Assignments,Assignment) {
- Num = split(Elements,Assignments,Sep)
- for (; Num; Num--) {
- Assignment = Assignments[Num]
- Ind = index(Assignment,AssignOp)
- Arr[substr(Assignment,1,Ind - 1)] = substr(Assignment,Ind + 1)
- }
- return Num
- }
-
- # Returns 1 if Set is empty, 0 if not.
- function IsEmpty(Set, i) {
- for (i in Set)
- return 0
- return 1
- }
-
- # MakeSet: make a set from a list.
- # An index with the name of each element of the list
- # is created in the given array.
- # Input variables:
- # Elements is a string containing the list of elements.
- # Sep is the character that separates the elements of the list.
- # Output variables:
- # Set is the array.
- # Return value: the number of elements added to the set.
- function MakeSet(Set,Elements,Sep, i,Num,Names) {
- Num = split(Elements,Names,Sep)
- for (i = 1; i <= Num; i++)
- Set[Names[i]]
- return Num
- }
-
- # Returns the number of elements in set Set
- function NumElem(Set, elem,Num) {
- for (elem in Set)
- Num++
- return Num
- }
-
- # Note: removed the code that treats -x specially from InitOpts()
- # so that -x can be used as a regular option for filegroup.
-
- # @(#) ProcArgs 1.2.2 94/09/23
- # 92/02/29 john h. dubois iii (john@armory.com)
- # 93/07/18 Added "#" arg type
- # 93/09/26 Do not count -h against MinArgs
- # 94/01/01 Stop scanning at first non-option arg. Added ">" option type.
- # Removed meaning of "+" or "-" by itself.
- # 94/03/08 Added & option and *()< option types.
- # 94/04/02 Added NoRCopt to Opts()
- # 94/06/11 Mark numeric variables as such.
- # 94/07/08 Opts(): Don't require any args if 'h' option is given.
- # 94/09/23 Fixed bug that caused fail if -opt<value> given as last arg.
-
- # optlist is a string which contains all of the possible command line options.
- # A character followed by certain characters indicates that the option takes
- # an argument, with type as follows:
- # : String argument
- # * Floating point argument
- # ( Non-negative floating point argument
- # ) Positive floating point argument
- # # Integer argument
- # < Non-negative integer argument
- # > Positive integer argument
- # The only difference the type of argument makes is in the runtime argument
- # error checking that is done.
-
- # The & option is a special case used to get numeric options without the
- # user having to give an option character. It is shorthand for [-+.0-9].
- # If & is included in optlist and an option string that begins with one of
- # these characters is seen, the value given to "&" will include the first
- # char of the option. & must be followed by a type character other than ":".
- # Note that if e.g. &> is given, an option of -.5 will produce an error.
-
- # Strings in argv[] which begin with "-" or "+" are taken to be
- # strings of options, except that a string which consists solely of "-"
- # or "+" is taken to be a non-option string; like other non-option strings,
- # it stops the scanning of argv and is left in argv[].
- # An argument of "--" or "++" also stops the scanning of argv[] but is removed.
- # If an option takes an argument, the argument may either immediately
- # follow it or be given separately.
- # "-" and "+" options are treated the same. "+" is allowed because most awks
- # take any -options to be arguments to themselves. gawk 2.15 was enhanced to
- # stop scanning when it encounters an unrecognized option, though until 2.15.5
- # this feature had a bug that caused problems in some cases.
-
- # If an option that does not take an argument is given,
- # an index with its name is created in Options and its value is set to "1".
- # If an option that does take an argument is given,
- # an index with its name is created in Options and its value
- # is set to the value of the argument given for it.
- # Options and their arguments are deleted from argv.
- # Note that this means that there may be gaps left in the indices of argv[].
- # If compress is nonzero, argv[] is packed by moving its elements so that
- # they have contiguous integer indices starting with 0.
- # argv[0] is not examined.
- # The number of arguments left in argc is returned.
- # If an error occurs, the global string OptErr is set to an error message
- # and -1 is returned.
- function ProcArgs(argc,argv,OptList,Options,compress,
- ArgNum,ArgsLeft,Arg,ArgLen,ArgInd,Option,Pos,NumOpt,Value,HadValue,
- NeedNextOpt,GotValue)
- {
- # ArgNum is the index of the argument being processed.
- # ArgsLeft is the number of arguments left in argv.
- # Arg is the argument being processed.
- # ArgLen is the length of the argument being processed.
- # ArgInd is the position of the character in Arg being processed.
- # Option is the character in Arg being processed.
- # Pos is the position in OptList of the option being processed.
- # NumOpt is true if a numeric option may be given.
- ArgsLeft = argc
- NumOpt = index(OptList,"&")
- for (ArgNum = 1; ArgNum < argc; ArgNum++) {
- if ((Arg = argv[ArgNum]) !~ /^[-+]./) # Not an option; quit
- break
- delete argv[ArgNum]
- ArgsLeft--
- if ((Arg == "--") || (Arg == "++"))
- break
- ArgLen = length(Arg)
- for (ArgInd = 2; ArgInd <= ArgLen; ArgInd++) {
- Option = substr(Arg,ArgInd,1)
- if (NumOpt && Option ~ /[-+.0-9]/) {
- Option = "&"
- Arg = "&" Arg
- ArgLen++
- Pos = NumOpt
- }
- else if (!(Pos = index(OptList,Option)) || Option == "&") {
- OptErr = "Invalid option: -" Option
- return -1
- }
-
- # Find what the value of the option will be if it needs one
- # NeedNextOpt is true if the option specifier is the last char of
- # this arg, which means that if the option requires a value it is
- # the next arg.
- if (NeedNextOpt = (ArgInd >= ArgLen)) { # Value is the next arg
- if (GotValue = ArgNum + 1 < argc)
- Value = argv[ArgNum+1]
- }
- else { # Value is included with option
- Value = substr(Arg,ArgInd + 1)
- GotValue = 1
- }
-
- if (HadValue = AssignVal(Option,Value,Options,
- substr(OptList,Pos + 1,1),GotValue)) {
- if (HadValue == -1)
- return -1
- if (NeedNextOpt) {
- delete argv[++ArgNum]
- ArgsLeft--
- }
- break # Used up this option
- }
- }
- }
- if (compress != 0)
- PackArr(argv,ArgsLeft)
- return ArgsLeft
- }
-
- # Global variables: OptErr
- # Return value: -1 on error, 0 if option did not require an argument,
- # 1 if it did.
- function AssignVal(Option,Value,Options,ArgType,GotValue,Name,
- UsedValue,Err) {
- # If option takes a value...
- if (UsedValue = (ArgType ~ "[:*()#<>]")) {
- if (!GotValue) {
- if (Name != "")
- OptErr = "Variable requires a value -- " Name
- else
- OptErr = "option requires an argument -- " Option
- return -1
- }
- if ((Err = CheckType(ArgType,Value,Option,Name)) != "") {
- OptErr = Err
- return -1
- }
- # Mark this as a numeric variable; will be propogated to Options[] val.
- if (ArgType != ":")
- Value += 0
- }
- else
- Value = 1
- if (!(Option in Options)) # Do not overwrite previously assigned values
- Options[Option] = Value
- return UsedValue
- }
-
- # Option is the option letter
- # Value is the value being assigned
- # Name is the var name of the option, if any
- # ArgType is one of:
- # : String argument
- # * Floating point argument
- # ( Non-negative floating point argument
- # ) Positive floating point argument
- # # Integer argument
- # < Non-negative integer argument
- # > Positive integer argument
- # Returns null on success, err string on error
- function CheckType(ArgType,Value,Option,Name, Err) {
- if (ArgType == ":")
- return ""
- # A number begins with option + or -, and is followed by a string of
- # digits or a decimal with digits before it, after it, or both
- if (Value !~ /^[-+]?([0-9]+|[0-9]+?\.[0-9]+|[0-9]+\.)$/)
- Err = "must be a number"
- else if (ArgType ~ "[#<>]" && Value ~ /\./)
- Err = "may not include a fraction"
- else if (ArgType ~ "[()<>]" && Value < 0)
- Err = "may not be negative"
- else if (ArgType ~ "[)>]" && Value == 0)
- Err = "must be a positive number"
- if (Err != "") {
- if (Name != "")
- return "Value assigned to variable " Name " " Err
- else {
- if (Option == "&")
- Option = Value
- return "Value assigned to option -" Option " " Err
- }
- }
- else
- return ""
- }
-
- # Packs Arr to indices starting with 0
- # Num should be the number of elements in Arr
- function PackArr(Arr,Num, NewInd,OldInd) {
- NewInd = OldInd = 0
- for (; Num; Num--) {
- while (!(OldInd in Arr))
- OldInd++
- if (NewInd != OldInd) {
- Arr[NewInd] = Arr[OldInd]
- delete Arr[OldInd]
- }
- OldInd++
- NewInd++
- }
- }
-
- # Note: only the above functions are needed by ProcArgs.
- # The rest of these functions call ProcArgs() and also do other
- # option-processing stuff.
-
- # Opts: Process command line arguments.
- # Opts processes command line arguments using ProcArgs()
- # and checks for errors. If an error occurs, a message is printed
- # and the program is exited.
- #
- # Input variables:
- # Name is the name of the program, for error messages.
- # Usage is a usage message, for error messages.
- # OptList the option description string, as used by ProcArgs().
- # MinArgs is the minimum number of non-option arguments that this
- # program should have, non including ARGV[0] and +h.
- # If the program does not require any non-option arguments,
- # MinArgs should be omitted or given as 0.
- # rcFile, if given, is the name of a file to read for variable initialization.
- # Values given in it will not override values given on the command line.
- # VarNames is a comma-separated list of variable names to map to options,
- # in the same order as the options are given in OptList.
- # If UseEnv is given and nonzero, the variables will also be searched for in
- # the environment. Values given in the environment will override those given
- # in the rcfile but not those given on the command line.
- # NoRCopt, if given, is an additional letter option that if given on the
- # command line prevents the rcfile from being read.
- # Special options:
- # If x is made an option and is given, some debugging info is output.
- # h is assumed to be the help option.
-
- # Global variables:
- # The command line arguments are taken from ARGV[].
- # The arguments that are option specifiers and values are removed from
- # ARGV[], leaving only ARGV[0] and the non-option arguments.
- # The number of elements in ARGV[] should be in ARGC.
- # After processing, ARGC is set to the number of elements left in ARGV[].
- # The option values are put in Options[].
- # On error, Err is set to 1 so it can be checked for in an END block.
-
- # Return value: The number of elements left in ARGV is returned.
-
- function Opts(Name,Usage,OptList,MinArgs,rcFile,VarNames,UseEnv,NoRCopt,
- ArgsLeft) {
- if (MinArgs == "")
- MinArgs = 0
- ArgsLeft = ProcArgs(ARGC,ARGV,OptList NoRCopt,Options,1)
- # if ((ArgsLeft + ("h" in Options)) < (MinArgs+1)) {
- if (ArgsLeft < (MinArgs+1) && !("h" in Options)) {
- if (ArgsLeft != -1)
- OptErr = "Not enough arguments"
- print Name ": " OptErr ". Use -h for help."
- print Usage
- Err = 1
- exit 1
- }
- if (rcFile != "" && (NoRCopt == "" || !(NoRCopt in Options)) &&
- InitOpts(rcFile,Options,OptList,VarNames,UseEnv) == -1)
- {
- print Name ": " OptErr ". Use -h for help."
- Err = 1
- exit 1
- }
- return ArgsLeft
- }
-
- # Global vars: sets OptErr; uses ENVIRON[];
- # if anything is read from the rcFile, sets READ_RCFILE to 1
- function InitOpts(rcFile,Options,OptTypes,VarNames,UseEnv,
- Line,Var,Pos,Vars,Map,CharOpt,NumVars,TypesInd,Types,Type,Ret) {
- NumVars = split(VarNames,Vars,",")
- TypesInd = Ret = 0
- for (i = 1; i <= NumVars; i++) {
- Var = Vars[i]
- CharOpt = substr(OptTypes,++TypesInd,1)
- if (CharOpt ~ "^[:*()#<>&]$")
- CharOpt = substr(OptTypes,++TypesInd,1)
- Map[Var] = CharOpt
- Types[Var] = Type = substr(OptTypes,TypesInd+1,1)
- # Do not overwrite entries from environment
- if (UseEnv && Var in ENVIRON && AssignVal(CharOpt,ENVIRON[Var],Options,
- Type,1,Var) == -1)
- return -1
- }
- if (rcFile ~ "^~/")
- rcFile = ENVIRON["HOME"] substr(rcFile,2)
- while ((getline Line < rcFile) == 1) {
- READ_RCFILE = 1
- if (Line !~ /^#/ && Line !~ "^[ \t]*$") {
- if (Pos = index(Line,"="))
- Var = substr(Line,1,Pos-1)
- else
- Var = Line # If no value, var is entire line
- if (Var in Map) {
- if (AssignVal(Map[Var],substr(Line,Pos+1),Options,
- Types[Var],Pos != 0,Var) == -1)
- return -1
- }
- else {
- OptErr = sprintf("Unknown var \"%s\" set in %s",Var,rcFile)
- Ret = -1
- }
- }
- }
- return Ret
- }
-